package com.hxh.controller;

import com.baomidou.mybatisplus.plugins.Page;
import com.hxh.entity.*;
import com.hxh.entity.input.ProjectTablePageConfigInput;
import com.hxh.entity.output.ApiResult;
import com.hxh.entity.po.ClassInfo;
import com.hxh.generater.springBoot.GenerationTableInfo;
import com.hxh.generater.vue.GenerationVueAdapter;
import com.hxh.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/projectTablePageConfig")
@Slf4j
public class ProjectTablePageConfigController {
    @Autowired
    ProjectTablePageConfigService projectTablePageConfigService;

    @Autowired
    ProjectService projectService;

    @Autowired
    TemplateConfigService templateConfigService;

    @Autowired
    TemplateFieldConfigService templateFieldConfigService;

    @Autowired
    ProjectTableFiledConfigService projectTableFiledConfigService;

    @Autowired
    GenerationVueAdapter generationVueAdapter;

    @Autowired
    ProjectConfigRecordService projectConfigRecordService;

    //获取项目-页面配置分页
    @RequestMapping(value = "/listPage", produces = "application/json;charset=utf-8")
    public ApiResult listPage(ProjectTablePageConfigInput pojo) {
        Page<ProjectTablePageConfig> page = new Page<>(pojo.getCurrent(), pojo.getPageSize());
        projectTablePageConfigService.listPage(page, pojo);
        return ApiResult.ok("获取项目-页面配置分页成功", page);
    }

    //新增项目-页面配置
    @PostMapping(value = "add")
    public ApiResult add(ProjectTablePageConfig projectTablePageConfig) {

        boolean flag = projectTablePageConfigService.insert(projectTablePageConfig);
        if (flag) {
            return ApiResult.ok("保存成功");
        }
        return ApiResult.fail("保存失败");
    }

    //修改项目-页面配置
    @PostMapping(value = "update")
    public ApiResult update(ProjectTablePageConfig projectTablePageConfig) {
        boolean flag = projectTablePageConfigService.update(projectTablePageConfig);
        if (flag) {
            return ApiResult.ok("更新成功");
        } else {
            return ApiResult.fail("更新失败");
        }
    }

    //删除项目-页面配置
    @PostMapping(value = "delete")
    public ApiResult deleteById(@RequestParam Integer id) {
        boolean flag = projectTablePageConfigService.deleteById(id);
        if (flag) {
            return ApiResult.ok("删除成功");
        } else {
            return ApiResult.fail("删除失败");
        }
    }

    //修改项目-页面配置
    @PostMapping(value = "createPage")
    public ApiResult createPage(@RequestParam String tableName, @RequestParam Integer projectId, @RequestParam Integer datasourceId) {
        try {
            Project project = projectService.selectById(projectId);
            ClassInfo classInfo = GenerationTableInfo.getTableInfo(project, datasourceId, tableName);
            generationVueAdapter.generationView(project, classInfo);
            String table = classInfo.getProjectDatasource().getMysqlDatabaseName() + "." + tableName;
            projectConfigRecordService.clearFrontRebuildFlag(projectId,table);
            return ApiResult.ok("生成页面成功");
        } catch (Exception e) {
            log.error("生成页面失败", e);
            return ApiResult.fail("生成页面失败");
        }
    }


    /**
     * 编辑页面时，检查每个字段可以出现的位置，如图片字段只能出现在编辑/新增/列表中，不能在搜索中
     * 判断方法：
     * 1、该字段配置过 字段映射，如配置映射成 图片类型
     * 2、该项目使用了某个模板 如 模板A
     * 3、该模板配置了模板-控件类型-允许出现的位置 如：模板A-图片类型-不允许出现在搜索框中
     *
     * @param projectId 项目id
     * @param tableName 表名
     *                  place     页面位置 位置：1:搜索框 2：table列表显示 3：新增/编辑
     */
    @PostMapping(value = "checkFieldPosition", produces = "application/json;charset=utf-8")
    public ApiResult checkFieldPosition(@RequestParam Integer projectId,
                                        @RequestParam Integer datasourceId,
                                        @RequestParam String tableName) {
        //1、项目id = 获取 模板 name
        Project project = projectService.selectById(projectId);
        if (project == null) {
            return ApiResult.fail("项目不存在！");
        }
        //2、模板 name = 模板 id
        String template = project.getTemplate();
        if (StringUtils.isBlank(template)) {
            return ApiResult.fail("项目模板未配置！");
        }
        TemplateConfig templateConfig = templateConfigService.getTemplateConfigByName(template);
        Integer templateConfigId = templateConfig.getId();
        //3、通过id获取全部的 模板可配置的字段映射类型管理
        List<TemplateFieldConfig> templateFieldConfigs = templateFieldConfigService.getTemplateFieldConfigByTemplateId(templateConfigId);
        if (CollectionUtils.isEmpty(templateFieldConfigs)) {
            return ApiResult.ok("模板未配置字段映射！");
        }
        Map<String, TemplateFieldConfig> componentNameToDataMap = new HashMap<>();
        componentNameToDataMap = templateFieldConfigs.stream().collect(Collectors.toMap(TemplateFieldConfig::getComponentName, Function.identity()));

        //4、通过项目id、表名 获取 项目表字段映射配置
        List<ProjectTableFiledConfig> projectTableFiledConfigs = projectTableFiledConfigService.selectByIdProjectIdTableNameFiledName(projectId,datasourceId, tableName);

        if (CollectionUtils.isEmpty(projectTableFiledConfigs)) {
            return ApiResult.ok("项目表未配置字段映射！");
        }

        Map<String, List<String>> placeNameToBanFieldNameMap = new HashMap<>();
        for (ProjectTableFiledConfig projectTableFiledConfig : projectTableFiledConfigs) {
            String showType = projectTableFiledConfig.getShowType();
            TemplateFieldConfig templateFieldConfig = componentNameToDataMap.get(showType);
            String placeType = templateFieldConfig.getPlaceType();
            if (!placeType.contains("1")) {
                List<String> stringList = placeNameToBanFieldNameMap.get("1");
                if (stringList == null) {
                    stringList = new ArrayList<>();
                }
                stringList.add(projectTableFiledConfig.getFiledName());
                placeNameToBanFieldNameMap.put("1", stringList);
            }
            if (!placeType.contains("2")) {
                List<String> stringList = placeNameToBanFieldNameMap.get("2");
                if (stringList == null) {
                    stringList = new ArrayList<>();
                }
                stringList.add(projectTableFiledConfig.getFiledName());
                placeNameToBanFieldNameMap.put("2", stringList);
            }
            if (!placeType.contains("3")) {
                List<String> stringList = placeNameToBanFieldNameMap.get("3");
                if (stringList == null) {
                    stringList = new ArrayList<>();
                }
                stringList.add(projectTableFiledConfig.getFiledName());
                placeNameToBanFieldNameMap.put("3", stringList);
            }
        }
        return ApiResult.ok("ok", placeNameToBanFieldNameMap);
    }

}
